package com.tsfyun.scm.service.impl.customs;

import cn.hutool.core.collection.CollUtil;
import com.tsfyun.common.base.enums.BillTypeEnum;
import com.tsfyun.common.base.exception.ServiceException;
import com.tsfyun.common.base.util.StringUtils;
import com.tsfyun.common.base.util.TsfPreconditions;
import com.tsfyun.scm.dto.customs.SaveDeclarationMemberElementsDTO;
import com.tsfyun.scm.entity.customs.Declaration;
import com.tsfyun.scm.entity.customs.DeclarationMember;
import com.tsfyun.scm.mapper.customs.DeclarationMemberMapper;
import com.tsfyun.scm.service.base.ISystemCacheService;
import com.tsfyun.scm.service.customs.IDeclarationMemberService;
import com.tsfyun.common.base.extension.ServiceImpl;
import com.tsfyun.scm.service.customs.IDeclarationService;
import com.tsfyun.scm.service.materiel.IMaterielBrandService;
import com.tsfyun.scm.system.vo.CustomsElementsVO;
import com.tsfyun.scm.util.MaterielUtil;
import com.tsfyun.scm.vo.customs.DeclarationMemberCustomsElementsVO;
import com.tsfyun.scm.vo.customs.DeclarationMemberVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 *
 * @since 2020-04-24
 */
@Slf4j
@Service
public class DeclarationMemberServiceImpl extends ServiceImpl<DeclarationMember> implements IDeclarationMemberService {

   @Autowired
   private ISystemCacheService systemCacheService;
    @Autowired
   private IDeclarationService declarationService;
   @Autowired
   private IMaterielBrandService materielBrandService;

   @Autowired
   private DeclarationMemberMapper declarationMemberMapper;

    @Override
    public List<DeclarationMemberVO> findByDeclarationId(Long declarationId) {
        DeclarationMember condition = new DeclarationMember();
        condition.setDeclarationId(declarationId);
        List<DeclarationMember> list = super.list(condition);
        List<DeclarationMemberVO> memberVOS = beanMapper.mapAsList(list,DeclarationMemberVO.class);
        if(CollUtil.isNotEmpty(list)) {

            memberVOS = memberVOS.stream().sorted(Comparator.comparing(DeclarationMemberVO::getRowNo)).collect(Collectors.toList());
        }
        return memberVOS;
    }

    @Override
    public DeclarationMemberCustomsElementsVO getMemberElements(Long id) {
        DeclarationMember declarationMember = super.getById(id);
        TsfPreconditions.checkArgument(Objects.nonNull(declarationMember), new ServiceException("报关单明细数据不存在"));
        //申报要素最后一位补空格
        String declareSpec = StringUtils.removeSpecialSymbol(declarationMember.getDeclareSpec())+" ";//根据海关编码获取申报要素
        String[] customsSpecs = declareSpec.split("\\|");
        List<CustomsElementsVO> elements = systemCacheService.getCustomsElementsByHsCode(declarationMember.getHsCode());
        Declaration declaration = declarationService.getById(declarationMember.getDeclarationId());
        BillTypeEnum billTypeEnum = BillTypeEnum.of(declaration.getBillType());
        for(int i = 0,size = elements.size(); i < size;i++){
            CustomsElementsVO customsElementsVO = elements.get(i);
            String val = "";
            if(!ArrayUtils.isEmpty(customsSpecs) && customsSpecs.length > i ) {
                val = customsSpecs[i];
            }
            if(MaterielUtil.ELEMENT_BRAND_MARK.equals(customsElementsVO.getName())){
                if(Objects.equals(billTypeEnum, BillTypeEnum.IMP)){  // 进口
                    //品牌
                    String brandZh = materielBrandService.findZhByNameEn(declarationMember.getBrand());
                    if(StringUtils.isEmpty(brandZh)){
                        throw new ServiceException(String.format("外文品牌：%s 未找到中文名称",declarationMember.getBrand()));
                    }
                    val = MaterielUtil.formatGoodsBrand(declarationMember.getBrand(),brandZh);
                }else if(Objects.equals(billTypeEnum,BillTypeEnum.EXP)){  // 出口
                    val = MaterielUtil.formatGoodsBrand(declarationMember.getBrand());
                }
            }else if(MaterielUtil.ELEMENT_MODEL_MARK.equals(customsElementsVO.getName())){
                //型号
                val = MaterielUtil.formatGoodsModel(declarationMember.getModel());
            }
            customsElementsVO.setVal(StringUtils.removeSpecialSymbol(val));
        }
        return new DeclarationMemberCustomsElementsVO(beanMapper.map(declarationMember,DeclarationMemberVO.class),elements);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveMemberElements(SaveDeclarationMemberElementsDTO dto) {
        DeclarationMember declarationMember = super.getById(dto.getId());
        TsfPreconditions.checkArgument(Objects.nonNull(declarationMember), new ServiceException("报关单明细数据不存在"));
        List<CustomsElementsVO> customsElements = systemCacheService.getCustomsElementsByHsCode(declarationMember.getHsCode());
        List<String> elementsVal = dto.getElementsVal();//填写的申报要素
        if(customsElements!=null&&customsElements.size()>0&&(elementsVal==null||customsElements.size()!=elementsVal.size())){
            TsfPreconditions.checkArgument(false,new ServiceException("申报要素错误，请刷新页面重试"));
        }
        Declaration declaration = declarationService.getById(declarationMember.getDeclarationId());
        BillTypeEnum billTypeEnum = BillTypeEnum.of(declaration.getBillType());
        List<String> declareSpecs = new ArrayList<>();
        for(int i=0;i<customsElements.size();i++){
            CustomsElementsVO customsElementsVO = customsElements.get(i);
            String val = StringUtils.removeSpecialSymbol(elementsVal.get(i));
            if(MaterielUtil.ELEMENT_BRAND_MARK.equals(customsElementsVO.getName())){
                if(Objects.equals(billTypeEnum,BillTypeEnum.IMP)){// 进口
                    //品牌
                    String brandZh = materielBrandService.findZhByNameEn(declarationMember.getBrand());
                    if(StringUtils.isEmpty(brandZh)){
                        throw new ServiceException(String.format("外文品牌：%s 未找到中文名称",declarationMember.getBrand()));
                    }
                    val = MaterielUtil.formatGoodsBrand(declarationMember.getBrand(),brandZh);
                }else if(Objects.equals(billTypeEnum,BillTypeEnum.EXP)){// 出口
                    val = MaterielUtil.formatGoodsBrand(declarationMember.getBrand());
                }
            }else if(MaterielUtil.ELEMENT_MODEL_MARK.equals(customsElementsVO.getName())){
                //型号
                val = MaterielUtil.formatGoodsModel(declarationMember.getModel());
            }
            if(Objects.equals(customsElementsVO.getIsNeed(),Boolean.TRUE)&&StringUtils.isEmpty(val)){
                throw new ServiceException(String.format("要素项【%s】必须填写",customsElementsVO.getName()));
            }
            declareSpecs.add(val);
        }

        //修改报关单明细数据
        DeclarationMember update = new DeclarationMember();
        update.setId(declarationMember.getId());
        update.setQuantity1(dto.getQuantity1());
        update.setQuantity2(dto.getQuantity2());
        if(StringUtils.isNotEmpty(declarationMember.getUnit2Name())&&(Objects.isNull(update.getQuantity2())||update.getQuantity2().compareTo(BigDecimal.ZERO)!=1)){
            throw new ServiceException("法二数量不能为空且必须大于零");
        }
        update.setDestinationCountry(dto.getDestinationCountry());
        update.setDestinationCountryName(dto.getDestinationCountryName());
        update.setDutyMode(dto.getDutyMode());
        update.setDutyModeName(dto.getDutyModeName());
        update.setDistrictCode(dto.getDistrictCode());
        update.setDistrictName(dto.getDistrictName());
        update.setCiqDestCode(dto.getCiqDestCode());
        update.setCiqDestName(dto.getCiqDestName());
        update.setDeclareSpec(String.join("|",declareSpecs));
        declarationMemberMapper.updateByPrimaryKeySelective(update);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeByDeclarationId(Long dclarationId) {
        declarationMemberMapper.removeByDeclarationId(dclarationId);
    }
}
